package com.gae.blore.client.map;

import static com.google.gwt.query.client.GQuery.$;

import org.gwtopenmaps.openlayers.client.LonLat;
import org.gwtopenmaps.openlayers.client.control.LayerSwitcher;
import org.gwtopenmaps.openlayers.client.control.PanZoomBar;
import org.gwtopenmaps.openlayers.client.feature.VectorFeature;
import org.gwtopenmaps.openlayers.client.layer.GMapType;
import org.gwtopenmaps.openlayers.client.layer.Google;
import org.gwtopenmaps.openlayers.client.layer.GoogleOptions;
import org.gwtopenmaps.openlayers.client.layer.Layer;
import org.gwtopenmaps.openlayers.client.layer.TransitionEffect;
import org.gwtopenmaps.openlayers.client.layer.WMS;
import org.gwtopenmaps.openlayers.client.layer.WMSOptions;
import org.gwtopenmaps.openlayers.client.layer.WMSParams;

import com.gae.blore.client.BusStopService;
import com.gae.blore.client.BusStopServiceAsync;
import com.gae.blore.client.FireBrigateStationService;
import com.gae.blore.client.FireBrigateStationServiceAsync;
import com.gae.blore.client.HospitalService;
import com.gae.blore.client.HospitalServiceAsync;
import com.gae.blore.client.MetroStationService;
import com.gae.blore.client.MetroStationServiceAsync;
import com.gae.blore.client.PoliceStationService;
import com.gae.blore.client.PoliceStationServiceAsync;
import com.gae.blore.client.RailwayStationService;
import com.gae.blore.client.RailwayStationServiceAsync;
import com.gae.blore.client.dialog.BusDetailsDialog;
import com.gae.blore.client.dialog.ErrorDialog;
import com.gae.blore.client.dialog.FireStationDialog;
import com.gae.blore.client.dialog.HospitalDialog;
import com.gae.blore.client.dialog.MetroStationDialog;
import com.gae.blore.client.dialog.PoliceStationDialog;
import com.gae.blore.client.dialog.RailStationDialog;
import com.gae.blore.client.domain.BusStop;
import com.gae.blore.client.domain.FireBrigadeStation;
import com.gae.blore.client.domain.Hospital;
import com.gae.blore.client.domain.MetroStation;
import com.gae.blore.client.domain.PoliceStation;
import com.gae.blore.client.domain.RailwayStation;
import com.gae.blore.client.layer.FeatureLayer;
import com.google.gwt.core.client.GWT;
import com.google.gwt.query.client.Function;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class NetworkMap {

	private MapWrapperPanel networkMap;
	private FeatureLayer featureLayer;
	private boolean isMapInitialized = false;

	private WMS wmsLayer;
	public static LonLat currentPosition;

	public static final String WMS_URL = "http://labs.metacarta.com/wms/vmap0";

	public NetworkMap() {

		networkMap = new MapWrapperPanel();

		// Defining a WMSLayer and adding it to a Map
		WMSParams wmsParams = new WMSParams();
		wmsParams.setFormat("image/png");
		wmsParams.setLayers("basic");
		wmsParams.setStyles("");
		// wmsParams.setIsTransparent(true);

		WMSOptions wmsLayerParams = new WMSOptions();
		// wmsLayerParams.setProjection("EPSG:2805");
		wmsLayerParams.setUntiled();
		wmsLayerParams.setTransitionEffect(TransitionEffect.RESIZE);
		GoogleOptions googleOptions = new GoogleOptions();

		googleOptions.setType(GMapType.G_NORMAL_MAP);
		googleOptions.setIsBaseLayer(true);
		googleOptions.setTransitionEffect(TransitionEffect.RESIZE);
		googleOptions.setNumZoomLevels(20);

		// googleOptions.setProjection("EPSG:4326");
		// googleOptions.setSphericalMercator(true);
		Google googleLayer = new Google("Google", googleOptions);

		wmsLayer = new WMS("Basic WMS", WMS_URL, wmsParams, wmsLayerParams);

		networkMap.getMap().addLayers(new Layer[] { googleLayer });

		// Adding controls to the Map
		networkMap.getMap().addControl(new PanZoomBar());
		// use NavToolbar instead of deprecated MouseToolbar
		// networkMap.getMap().addControl(new NavToolbar());

		// networkMap.getMap().addControl(new MousePosition());
		networkMap.getMap().addControl(new LayerSwitcher());

		LonLat center = new LonLat(77.5946, 12.9716);
		// Center and Zoom
		networkMap.getMap().setCenter(center, 13);
		featureLayer = new FeatureLayer(networkMap.getMap());

	}

	public MapWrapperPanel getNetworkMap() {
		return this.networkMap;
	}

	public FeatureLayer getFeatureLayer() {
		return featureLayer;
	}

	public void init() {

		$(".olMap").bind(Event.ONCLICK, null, new Function() {
			@Override
			public boolean f(final Event e) {
				if (!isMapInitialized) {
					$(".olMap").css("width", "701px");
					$(".olMap").css("height", "501px");
					networkMap.getMap().updateSize();
					isMapInitialized = true;
				}

				String id = e.getTarget().getPropertyString("_featureId");

				if (null == id) {

				} else {
					VectorFeature feature = featureLayer.getFeature(id);
					String type = feature.getAttributes().getAttributeAsString(
							"type");
					if (type.equals("BusStop")) {
						handleBusDetails(feature, e);
					} else if (type.equals("Hospital")) {
						handleHospitalDetails(feature, e);
					} else if (type.equals("PoliceStation")) {
						handlePoliceStationDetails(feature, e);
					} else if (type.equals("MetroStation")) {
						handleMetroStationDetails(feature, e);
					} else if (type.equals("RailwayStation")) {
						handleRailStationDetails(feature, e);
					} else if (type.equals("FireBrigade")) {
						handleFireStationDetails(feature, e);
					}

				}
				return false;
			}
		});

	}

	private void handleBusDetails(final VectorFeature feature, final Event e) {
		final BusStopServiceAsync busStopService = GWT
				.create(BusStopService.class);
		Long busId = new Long(feature.getAttributes().getAttributeAsInt("id"));
		busStopService.getBusStop(busId, new AsyncCallback<BusStop>() {

			@Override
			public void onSuccess(BusStop result) {

				BusDetailsDialog busDetailsDialog = new BusDetailsDialog(result);
				busDetailsDialog.center();

			}

			@Override
			public void onFailure(Throwable caught) {
				handleError();
			}
		});
	}

	private void handlePoliceStationDetails(final VectorFeature feature,
			final Event e) {

		final PoliceStationServiceAsync policeServiceAsync = GWT
				.create(PoliceStationService.class);
		Long polId = new Long(feature.getAttributes().getAttributeAsInt("id"));

		policeServiceAsync.getPoliceStation(polId,
				new AsyncCallback<PoliceStation>() {

					@Override
					public void onFailure(Throwable caught) {
						handleError();

					}

					@Override
					public void onSuccess(PoliceStation result) {

						PoliceStationDialog polDetailsDialog = new PoliceStationDialog(
								result);
						polDetailsDialog.center();

					}
				});

	}

	private void handleRailStationDetails(final VectorFeature feature,
			final Event e) {

		final RailwayStationServiceAsync railServiceAsync = GWT
				.create(RailwayStationService.class);
		Long railId = new Long(feature.getAttributes().getAttributeAsInt("id"));

		railServiceAsync.getRailwayStation(railId,
				new AsyncCallback<RailwayStation>() {

					@Override
					public void onSuccess(RailwayStation result) {

						RailStationDialog railDetailsDialog = new RailStationDialog(
								result);

						railDetailsDialog.center();

					}

					@Override
					public void onFailure(Throwable caught) {
						handleError();

					}
				});

	}

	private void handleMetroStationDetails(final VectorFeature feature,
			final Event e) {

		final MetroStationServiceAsync metroServiceAsync = GWT
				.create(MetroStationService.class);
		Long metroId = new Long(feature.getAttributes().getAttributeAsInt("id"));

		metroServiceAsync.getMetroStation(metroId,
				new AsyncCallback<MetroStation>() {

					@Override
					public void onFailure(Throwable caught) {
						handleError();

					}

					@Override
					public void onSuccess(MetroStation result) {

						MetroStationDialog metroDetailsDialog = new MetroStationDialog(
								result);

						metroDetailsDialog.center();

					}
				});

	}

	private void handleFireStationDetails(final VectorFeature feature,
			final Event e) {

		final FireBrigateStationServiceAsync fireServiceAsync = GWT
				.create(FireBrigateStationService.class);
		Long fireId = new Long(feature.getAttributes().getAttributeAsInt("id"));

		fireServiceAsync.getFireBrigadeStation(fireId,
				new AsyncCallback<FireBrigadeStation>() {

					@Override
					public void onFailure(Throwable caught) {
						handleError();

					}

					@Override
					public void onSuccess(FireBrigadeStation result) {

						FireStationDialog fireDetailsDialog = new FireStationDialog(
								result);
						fireDetailsDialog.center();

					}
				});

	}

	private void handleHospitalDetails(final VectorFeature feature,
			final Event e) {

		final HospitalServiceAsync hospitalServiceAsync = GWT
				.create(HospitalService.class);
		Long hospId = new Long(feature.getAttributes().getAttributeAsInt("id"));

		hospitalServiceAsync.getHospital(hospId, new AsyncCallback<Hospital>() {

			@Override
			public void onFailure(Throwable caught) {
				handleError();
			}

			@Override
			public void onSuccess(Hospital result) {

				HospitalDialog hospDetailsDialog = new HospitalDialog(result);
				hospDetailsDialog.center();

			}
		});

	}

	private void handleError() {
		ErrorDialog errorDialog = new ErrorDialog();
		errorDialog.center();

	}
}
